#include <iostream>
#include <unistd.h>
#include <cerrno>
#include <cstring>
#include <sys/types.h>

//任何一中通信方案，都必须先让不同的进程看到同一份资源
int main()
{
    //1.创建管道
    int pipefd[2] = {0};

    int ret = pipe(pipefd);
    if(ret < 0)
    {
        //创建管道失败
        std::cout << "pipe error, " << errno << strerror(errno) << std::endl;
    }

    std::cout << "pipefd[0]: " << pipefd[0] << std::endl;//3 读 -- 嘴巴
    std::cout << "pipefd[1]: " << pipefd[1] << std::endl;//4 写 -- 笔
    
    //2.创建子进程
    pid_t id = fork();
    if(id == -1)
    {
        //创建子进程失败
        perror("fork filed::");
        exit(-1);
    }


    //这里让子进程写，父进程读
    if(id == 0)
    {
        //子进程
        //3.关闭对应的fd
        close(pipefd[0]);

        std::string str = "holle, i am child";
        int cnt = 1;
        char buffer[1024];
        while(true)
        {
            snprintf(buffer, sizeof buffer, "%s, %d, my pid:%d.\n", str.c_str(), cnt++, getpid());
            write(pipefd[1], buffer, strlen(buffer));
            sleep(1);
        }
        exit(pipefd[1]);//文件描述符是随进程的，这里不关闭也可以，子进程退出的时候，自动就关闭了
        exit(0);
    }

    //父进程
    close(pipefd[1]);
    
    char buffer[1024];
    while (true)
    {
        //从管道中读取数据
        int n = read(pipefd[0], buffer, sizeof(buffer) - 1);
        if(n > 0)
        {
            buffer[n] = '\0';
        }
        std::cout << "i am parent, child give me message: " << buffer << std::endl;
    }
    
    close(pipefd[0]);
    return 0;
}

//2023-5-6
